import { Tileset, Tile, BoundingVolume, ValidationResult } from './types';

/**
 * Tileset 验证器
 * 负责验证 tileset 结构是否符合 3D Tiles 规范
 */
export class TilesetValidator {
  /**
   * 验证整个 tileset
   * @param tileset 要验证的 tileset 对象
   * @returns 验证结果
   */
  validate(tileset: Tileset): ValidationResult {
    const result: ValidationResult = {
      valid: true,
      errors: [],
      warnings: []
    };

    // 验证顶层必填字段
    this.validateAsset(tileset.asset, result);

    if (tileset.geometricError === undefined || typeof tileset.geometricError !== 'number' || tileset.geometricError < 0) {
      result.errors.push('Tileset must have a valid geometricError (non-negative number)');
      result.valid = false;
    }

    if (!tileset.root) {
      result.errors.push('Tileset must have a root tile');
      result.valid = false;
    } else {
      // 验证根瓦片及其子瓦片
      this.validateTile(tileset.root, tileset.geometricError, result);
    }

    return result;
  }

  /**
   * 验证 asset 字段
   */
  private validateAsset(asset: any, result: ValidationResult) {
    if (!asset) {
      result.errors.push('Tileset must have an asset');
      result.valid = false;
      return;
    }

    if (!asset.version || typeof asset.version !== 'string') {
      result.errors.push('Asset must have a valid version string');
      result.valid = false;
    } else if (!this.isValidVersion(asset.version)) {
      result.warnings.push(`Unsupported version ${asset.version}, supported versions are 1.0 and 1.1`);
    }
  }

  /**
   * 验证瓦片
   * @param tile 要验证的瓦片
   * @param parentGeometricError 父瓦片的几何误差
   * @param result 验证结果
   */
  private validateTile(tile: Tile, parentGeometricError: number, result: ValidationResult) {
    // 验证 boundingVolume
    if (!tile.boundingVolume) {
      result.errors.push('Tile must have a boundingVolume');
      result.valid = false;
    } else {
      this.validateBoundingVolume(tile.boundingVolume, result);
    }

    // 验证 geometricError
    if (tile.geometricError === undefined || typeof tile.geometricError !== 'number' || tile.geometricError < 0) {
      result.errors.push('Tile must have a valid geometricError (non-negative number)');
      result.valid = false;
    } else if (tile.geometricError >= parentGeometricError) {
      result.errors.push(`Tile's geometricError (${tile.geometricError}) must be less than parent's (${parentGeometricError})`);
      result.valid = false;
    }

    // 验证 refine 字段（如果存在）
    if (tile.refine && tile.refine !== 'REPLACE' && tile.refine !== 'ADD') {
      result.errors.push(`Tile has invalid refine value: ${tile.refine}, must be 'REPLACE' or 'ADD'`);
      result.valid = false;
    }

    // 验证 content（如果存在）
    if (tile.content && tile.content.uri && typeof tile.content.uri !== 'string') {
      result.errors.push('Tile content must have a valid uri string');
      result.valid = false;
    }

    // 递归验证子瓦片
    if (tile.children && Array.isArray(tile.children)) {
      tile.children.forEach(child => {
        this.validateTile(child, tile.geometricError, result);
      });
    } else if (tile.children) {
      result.errors.push('Tile children must be an array');
      result.valid = false;
    }
  }

  /**
   * 验证包围体
   */
  private validateBoundingVolume(boundingVolume: BoundingVolume, result: ValidationResult) {
    const types = [];
    if (boundingVolume.region) types.push('region');
    if (boundingVolume.box) types.push('box');
    if (boundingVolume.sphere) types.push('sphere');

    if (types.length === 0) {
      result.errors.push('BoundingVolume must have one of: region, box, or sphere');
      result.valid = false;
      return;
    }

    if (types.length > 1) {
      result.errors.push(`BoundingVolume must have only one type, found: ${types.join(', ')}`);
      result.valid = false;
    }

    // 验证每种类型的结构
    if (boundingVolume.region) {
      if (!Array.isArray(boundingVolume.region) || boundingVolume.region.length !== 6) {
        result.errors.push('Region must be an array of 6 numbers');
        result.valid = false;
      }
    }

    if (boundingVolume.box) {
      if (!Array.isArray(boundingVolume.box) || boundingVolume.box.length !== 6) {
        result.errors.push('Box must be an array of 6 numbers');
        result.valid = false;
      }
    }

    if (boundingVolume.sphere) {
      if (!Array.isArray(boundingVolume.sphere) || boundingVolume.sphere.length !== 4) {
        result.errors.push('Sphere must be an array of 4 numbers');
        result.valid = false;
      }
    }
  }

  /**
   * 检查版本是否有效
   */
  private isValidVersion(version: string): boolean {
    return version === '1.0' || version === '1.1';
  }
}